package com.zhan.ielts.web.controller;

import com.zhan.frame.core.dao.BaseService;
import com.zhan.frame.core.web.controller.BaseControllerImpl;
import com.zhan.frame.core.web.domain.CustomResult;
import com.zhan.frame.core.web.domain.Result;
import com.zhan.ielts.dao.ParamDao;
import com.zhan.ielts.domain.FilterWord;
import com.zhan.ielts.domain.SpeakingRecall;
import com.zhan.ielts.domain.query.SpeakingRecallQuery;
import com.zhan.ielts.domain.vo.SpeakingRecallVo;
import com.zhan.ielts.domain.Param;
import com.zhan.ielts.service.*;
import com.zhan.ielts.utils.CustomPropertisUtils;
import net.sf.json.JSONArray;
import com.zhan.ielts.utils.Contents;
import com.zhan.ielts.utils.SendSMSSelf;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.zhan.ielts.service.SpeakingRecallService;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/speaking/recall")
public class SpeakingRecallController extends BaseControllerImpl<SpeakingRecall, SpeakingRecallQuery> {

    private Logger log = LoggerFactory.getLogger(SpeakingRecallController.class);

    @Autowired
    private SpeakingRecallService speakingRecallService;
    @Autowired
    private FilterWordService filterWordService;

    @Autowired
    EmailService emailService;

    @Autowired
    private ParamDao paramDao;
    @Autowired
    private ParamService paramService;
    @Override
    protected BaseService<SpeakingRecall> getBaseService() {
        return speakingRecallService;
    }

    @ResponseBody
    @RequestMapping(value = "/pushmessage/{id}", method = RequestMethod.POST)
    public CustomResult pushMessage(@PathVariable("id") String id) {
        Map map = new HashMap();
        try {
            SpeakingRecall recall = speakingRecallService.queryById(id);
            if (recall != null) {
                String mess = speakingRecallService.pushMessage(recall);
                if ("fail".equals(mess)) {
                    return new CustomResult(0, "网络或系统错误!", map);
                }
            }
        } catch (Exception e) {
            // return new Result(Status.ERROR, "网络或系统错误！");
            return new CustomResult(0, "网络或系统错误!", map);
        }

        // return new Result(Status.OK, map);
        return new CustomResult(1, "", map);
//		return new CustomResult(1, "", list);

    }

    @ResponseBody
    @RequestMapping(value = "/pushmgs", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public CustomResult pushMessages(String[] ids) {
        Map map = new HashMap();
        try {
            if (ids != null) {
                if (ids.length > 0) {
                    for (String id : ids) {
                        SpeakingRecall recall = speakingRecallService.queryById(id);
                        if (recall != null) {
                            speakingRecallService.pushMessage(recall);
                        }
                    }
                }
            }
        } catch (Exception e) {
            // return new Result(Status.ERROR, "网络或系统错误！");
            return new CustomResult(0, "网络或系统错误!", map);
        }

        // return new Result(Status.OK, map);
        return new CustomResult(1, "", map);
//		return new CustomResult(1, "", list);

    }

    @SuppressWarnings({"rawtypes"})
    @ResponseBody
    @RequestMapping(value = "/fetch", method = RequestMethod.POST)
    public CustomResult fetchSpeakingRecall(String userId, String universityCode, String cityCode, Long publishTime) {
        log.debug("获取口语回忆开始");
        Map map = new HashMap();

        try {
            SpeakingRecallVo speakingRecall = new SpeakingRecallVo();
            speakingRecall.setPublishTime(publishTime);
            speakingRecall.setUniversityCode(universityCode);
            speakingRecall.setCityCode(cityCode);
            speakingRecall.setStatus(0);
            Sort sort = new Sort(Direction.DESC, "publish_time");
            Pageable pageable = new PageRequest(0, 10, sort);

            map = speakingRecallService.fetchSpeakingRecall(speakingRecall, pageable);
            log.debug("获取口语回忆结束");
        } catch (Exception e) {
            e.printStackTrace();
            // return new Result(Status.ERROR, "网络或系统错误！");
            return new CustomResult(0, "网络或系统错误！", map);
        }

        // return new Result(Status.OK, map);
        return new CustomResult(1, "", map);
//		return new CustomResult(1, "", list);

    }

    @SuppressWarnings("rawtypes")
    @ResponseBody
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public CustomResult update(SpeakingRecall speakingRecall) {
        log.debug("更新口语回忆开始");
        Map map = new HashMap();

        if (StringUtils.isEmpty(speakingRecall.getUserId())) {
            return new CustomResult(0, "userId为空！", map);
        }
        boolean isLegal = true;
        try {
            speakingRecall.setPublishTime(System.currentTimeMillis());
            Integer sum = getFilterWordWeight(speakingRecall.getData());
            if (sum != null && sum > 8) {
                speakingRecall.setStatus(1);
                isLegal = false;
            } else {
                speakingRecall.setStatus(0);
            }
            speakingRecallService.insert(speakingRecall);
        } catch (Exception e) {
            e.printStackTrace();
            // return new Result(Status.ERROR, "网络或系统错误！");
            return new CustomResult(0, "网络或系统错误！", map);
        }
        log.debug("更新口语回忆开始");
        if (isLegal) {
            return new CustomResult(1, "", map);
        } else {
            return new CustomResult(0, "提交失败", map);
        }
    }


    @Override
    @ResponseBody
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Result deleteList(String[] ids) {
        if (ArrayUtils.isEmpty(ids)) {
            log.error("未设置批量删除对象的ID号！对象：{}", path.getEntityName());
            return new Result(Result.Status.ERROR, "没有传入要删除的ID号数组！");
        }
        try {
            List<String> idList = Arrays.asList(ids);
            SpeakingRecallQuery query = new SpeakingRecallQuery();
            query.setIds(idList);
            List<SpeakingRecall> speakingRecallList = speakingRecallService.queryList(query);
            for (SpeakingRecall speakingRecall : speakingRecallList) {
                speakingRecall.setStatus(1);
                speakingRecall.setNeedReview(1);
            }
            getBaseService().updateInBatch(speakingRecallList);
        } catch (Exception e) {
            log.error("批量删除对象失败！对象:" + path.getEntityName(), e);
            return new Result(Result.Status.ERROR, "批量删除失败！");
        }
        return new Result(Result.Status.OK, ids.length);
    }


    private Integer getFilterWordWeight(String str) {
        if (str == null) {
            return null;
        }
        String temp = str.replaceAll(" ", "").toLowerCase();
        List<FilterWord> list = filterWordService.queryAll();
        Integer sum = 0;
        if (list != null) {
            for (FilterWord f : list) {
                if (temp.contains(f.getName())) {
                    sum = sum + f.getWeight();
                }
            }
        }
        if (sum > 0) {
            return sum;
        }
        return null;
    }

    @ResponseBody
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    public CustomResult importCustomData(@RequestParam(value = "file", required = false) MultipartFile file) {
        log.debug("导入口语回忆开始");
        Map map = new HashMap();

        if (file.isEmpty()) {
            return new CustomResult(0, "file 为空！", map);
        }

        try {

            String fileFolder = CustomPropertisUtils.getProperties("filePath");
            String aliyunFolder = CustomPropertisUtils.getProperties("aliyunTopicPath");

            speakingRecallService.importSpeakingRecall(file, fileFolder, aliyunFolder);
        } catch (Exception e) {
            e.printStackTrace();
            return new CustomResult(0, "系统错误！", map);
        }
        log.debug("导入口语回忆结束");
        return new CustomResult(1, "", map);

    }


    @Override
    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView selectList(SpeakingRecallQuery query, @PageableDefault Pageable pageable) {
        Page<SpeakingRecall> page = getBaseService().queryPageList(query, pageable);
        ModelAndView mav = new ModelAndView(path.getListViewPath()/*"/speaking/recall/listReviewRecall"*/, "page", page);
        List<SpeakingRecall> list = page.getContent();
        if (!CollectionUtils.isEmpty(list)) {
            for (SpeakingRecall speakingRecall : list) {
                if(speakingRecall.getData().startsWith("[")){
                    speakingRecall.setData(dealWithData(speakingRecall.getData()));
                }
            }
        }
        mav.addObject("query", query);
        return mav;
    }
    private String dealWithData(String data) {
        JSONArray arr = JSONArray.fromObject(data);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.size(); i++) {
            JSONObject o = (JSONObject)arr.get(i);
            sb.append(o.get("title")).append(":").append(o.get("content")).append("<br>");
        }
        return sb.toString();
    }


    @SuppressWarnings("rawtypes")
    @ResponseBody
    @RequestMapping(value = "/fetch/review", method = RequestMethod.POST)
    public Result selectList(SpeakingRecall query, @PageableDefault Pageable pageable) {
        Map map = null;
        try {
            List<SpeakingRecall> list = getBaseService().queryList(query, pageable);

            JSONArray jsonArray = JSONArray.fromObject(list);
            for(int i =0; i<jsonArray.size();i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if(null == jsonObject.getString("data") || "".equals(jsonObject.getString("data"))){
                    jsonObject.element("data", new JSONArray());
                } else {
                    jsonObject.element("data", jsonArray.fromObject(jsonObject.getString("data")));
                }
            }
            map = new HashMap();
            map.put("data", jsonArray);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Result.Status.ERROR, "网络或系统错误！");
        }
        return new Result(Result.Status.OK, map);
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public ModelAndView editView(@PathVariable("id") String id) {
        SpeakingRecall speakingRecall = getBaseService().queryById(id);
        speakingRecall.setReviewer("");
        return new ModelAndView("/speaking/recall/editReviewRecall", "speakingRecall", speakingRecall);
    }

    @RequestMapping(value = "/edit/{id}/{reviewer}", method = RequestMethod.GET)
    public ModelAndView editView(@PathVariable("id") String id, @PathVariable("reviewer") String reviewer) {
        SpeakingRecall speakingRecall = getBaseService().queryById(id);
        speakingRecall.setReviewer(reviewer);
        return new ModelAndView("/speaking/recall/editReviewRecall", "speakingRecall", speakingRecall);
    }

    @RequestMapping(value = "/editListView", method = RequestMethod.GET)
    public String editListView(Model model,String ids, String reviewer) {
//        Map speakingRecall = new HashMap();
//        speakingRecall.put("ids", ids);
//        speakingRecall.put("reviewer", reviewer);
        model.addAttribute("ids", ids);
        model.addAttribute("reviewer", reviewer);
        return "/speaking/recall/editReviewRecallList";
    }

    @RequestMapping(value = "/editOne", method = RequestMethod.POST)
    public ModelAndView editSpeakingRecall(SpeakingRecallQuery query) {
        getBaseService().updateByIdSelective(query);
        if (TextUtils.isEmpty(query.getReviewer())) {
            return new ModelAndView("redirect:/speaking/recall/");
        } else {
            return new ModelAndView("redirect:/speaking/recall/review?reviewer=" + query.getReviewer());
        }
    }

    @RequestMapping(value = "/editList", method = RequestMethod.POST)
    public ModelAndView editSpeakingRecallList(String ids, int status, String reviewer) {
        String[] idArr = ids.split(",");
        List<String> idList = Arrays.asList(idArr);
        SpeakingRecallQuery query = new SpeakingRecallQuery();
        query.setIds(idList);
        List<SpeakingRecall> speakingRecallList = speakingRecallService.queryList(query);
        for (SpeakingRecall speakingRecall : speakingRecallList) {
            speakingRecall.setStatus(status);
            speakingRecall.setReviewer(reviewer);
            speakingRecall.setNeedReview(1);
            getBaseService().updateByIdSelective(speakingRecall);
            if (status == 0) {
                speakingRecallService.addNewCount(speakingRecall);
//                speakingRecallService.pushMessage(speakingRecall);
            }
        }
//        getBaseService().updateInBatch(speakingRecallList);
        if (!TextUtils.isEmpty(reviewer)) {
            String url = "redirect:/speaking/recall/review?reviewer=" + reviewer;
            return new ModelAndView(url);
        } else {
            return new ModelAndView("redirect:/speaking/recall");
        }
    }


    @RequestMapping(value = "/review", method = RequestMethod.GET)
    public ModelAndView selectReviewList(SpeakingRecall speakingRecall,@RequestParam String reviewer,@PageableDefault(sort = {"publish_time"}, direction = Sort.Direction.DESC) Pageable pageable) {
        ModelAndView mav = null;
        try {
            if(TextUtils.isEmpty(reviewer)) {
                return new ModelAndView();
            }
            if(speakingRecall.getNeedReview() == null) {
                speakingRecall.setNeedReview(2);
            }
            speakingRecall.setReviewer(reviewer);
            Page<SpeakingRecallVo> page = speakingRecallService.selectReviewList(speakingRecall, pageable);
            mav = new ModelAndView(/*path.getListViewPath()*/"/speaking/recall/listReviewRecall", "page", page);
            List<SpeakingRecallVo> list = page.getContent();
            if (!CollectionUtils.isEmpty(list)) {
                for (SpeakingRecallVo recall : list) {
                    if(recall.getData().startsWith("[")){
                        recall.setData(dealWithData(recall.getData()));
                    }
                }
            }
            mav.addObject("query", speakingRecall);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mav;
    }


    @ResponseBody
    @RequestMapping(value = "/review/pass/", method = RequestMethod.POST)
    public Result reviewOne(@RequestBody SpeakingRecall speakingRecall) {
        try {
            getBaseService().updateByIdSelective(speakingRecall);

            if(speakingRecall.getStatus() == 0) {
                SpeakingRecall query = getBaseService().queryById(speakingRecall.getId());
                speakingRecallService.addNewCount(query);
//                speakingRecallService.pushMessage(query);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Result.Status.ERROR, "网络或系统错误");
        }
        return new Result(Result.Status.OK, "审核通过");
    }

    @SuppressWarnings("rawtypes")
    @ResponseBody
    @RequestMapping(value = "/send", method = RequestMethod.GET)
    public CustomResult sendSms() {
        SpeakingRecall query = new SpeakingRecall();
        query.setNeedReview(2);
        Integer count = speakingRecallService.selectUntreatedCount(query);
        boolean isLegal = false;
        if (null != count && count > 0) {
            isLegal = sendSms(count);
        }
//        boolean isLegal = sendSms(1);
        log.debug("更新口语回忆开始");
        if (isLegal) {
            return new CustomResult(1, "", isLegal);
        } else {
            return new CustomResult(0, "提交失败", isLegal);
        }
    }


    private boolean sendSms(int count){
        Param param = new Param();
        param.setType(Contents.SMS_TYPE);
        param.setParamName(Contents.SMS_PHONE_PARAM_NAME);
        param = paramDao.selectOne(param);

        boolean flag = false;
        Param paramContent = new Param();
        paramContent.setType(Contents.SMS_TYPE);
        paramContent.setParamName(Contents.SMS_CONTENT_PARAM_NAME);
        paramContent = paramDao.selectOne(paramContent);
        String phoneName = param.getParamValue();
        phoneName = "cc:18516577520";
        String[] phoneNames = phoneName.split(",");
        for (int i = 0; i < phoneNames.length; i++) {
            String[] nameAndPhone = phoneNames[i].split(":");
            String content = String.format(paramContent.getParamValue(), nameAndPhone[0], count);
            flag = SendSMSSelf.sendSMS(nameAndPhone[1], content, Contents.SMS_TOKEN_UNSET);
        }
        Param paramMail = new Param();
        paramMail.setType(Contents.MAIL_TYPE);
        paramMail.setParamName(Contents.MAIL_ADDRESS);
        paramMail = paramDao.selectOne(paramMail);
        String email = paramMail.getParamValue();
        email = "568275828@qq.com";
        String[] emails = email.split(",");
        try {
            String content = String.format(paramContent.getParamValue(), "  ", count);
            emailService.sendMailCommen("有待审核口语回忆", content, emails);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return flag;
    }
}
